package it.uniroma2.art.coda.projectionrule;

import it.uniroma2.art.coda.projectionrule.graph.GraphSingleElemVar;
import it.uniroma2.art.coda.projectionrule.graph.GraphSingleElement;

/**
 * This class represent the graph element (the triple, not the single element inside it)
 * 
 * @author Andrea Turbati
 * 
 */
public class GraphStruct {
	private GraphSingleElement subj;
	private GraphSingleElement pred;
	private GraphSingleElement obj;
	private ProjectionRule prRule;
	private boolean issueWithPRRule;
	private boolean isOptional;

	/**
	 * @param subj
	 *            the subject of the triple
	 * @param pred
	 *            the predicate of the triple
	 * @param obj
	 *            the object of the triple
	 */
	public GraphStruct(GraphSingleElement subj, GraphSingleElement pred, GraphSingleElement obj) {
		initialize(subj, pred, obj, false);
	}

	/**
	 * @param subj
	 *            the subject of the triple
	 * @param pred
	 *            the predicate of the triple
	 * @param obj
	 *            the object of the triple
	 * @param isOptional
	 *            true if the triple is optional, false otherwise
	 */
	public GraphStruct(GraphSingleElement subj, GraphSingleElement pred, GraphSingleElement obj,
			boolean isOptional) {
		initialize(subj, pred, obj, isOptional);
	}

	private void initialize(GraphSingleElement subj, GraphSingleElement pred, GraphSingleElement obj,
			boolean isOptional) {
		this.subj = subj;
		this.pred = pred;
		this.obj = obj;
		if (subj.getPRRule() == pred.getPRRule() && pred.getPRRule() == obj.getPRRule()) {
			prRule = subj.getPRRule();
			issueWithPRRule = false;
		} else {
			prRule = null;
			issueWithPRRule = true;
		}
		this.isOptional = isOptional;
	}

	/**
	 * See if this triple has any issue
	 * 
	 * @return true if the triple has any issue, false otherwise
	 */
	public boolean hasIssue() {
		return (issueWithPRRule || subj.hasIssue() || pred.hasIssue() || obj.hasIssue());
	}

	/**
	 * check if this triple contains at least one variable
	 * 
	 * @return true if this triple contains at least one variable
	 */
	public boolean containsVarWhere() {
		return ((subj instanceof GraphSingleElemVar) || (pred instanceof GraphSingleElemVar) || (obj instanceof GraphSingleElemVar));
	}

	/**
	 * Get the subject of the triple
	 * 
	 * @return the subject of the triple
	 */
	public GraphSingleElement getSubj() {
		return subj;
	}

	/**
	 * Get the predicate of the triple
	 * 
	 * @return the predicate of the triple
	 */
	public GraphSingleElement getPred() {
		return pred;
	}

	/**
	 * Get the object of the triple
	 * 
	 * @return the object of the triple
	 */
	public GraphSingleElement getObj() {
		return obj;
	}

	/**
	 * Get the Projection Rule
	 * 
	 * @return the Projection Rule
	 */
	public ProjectionRule getPRRule() {
		return prRule;
	}

	/**
	 * Check if the triple if optional
	 * 
	 * @return true if the triple is optional false otherwise
	 */
	public boolean isOptional() {
		return isOptional;
	}
}
